package org.changs.aplug.base;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.app.Fragment;

import com.trello.rxlifecycle2.android.ActivityEvent;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;

import org.changs.aplug.AplugManager;
import org.changs.aplug.interf.OnBackPressedListener;

import javax.inject.Inject;

import dagger.android.AndroidInjection;
import dagger.android.AndroidInjector;
import dagger.android.DispatchingAndroidInjector;
import dagger.android.HasFragmentInjector;
import dagger.android.support.HasSupportFragmentInjector;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by yincs on 2017/7/20.
 */

public abstract class BaseActivity extends RxAppCompatActivity implements IView,
        HasFragmentInjector, HasSupportFragmentInjector {

    @Inject DispatchingAndroidInjector<Fragment> supportFragmentInjector;
    @Inject DispatchingAndroidInjector<android.app.Fragment> frameworkFragmentInjector;
    private IDelegateOpt mDelegateOpt;
    private OnBackPressedListener mOnBackPressedListener;

    @Override
    public AndroidInjector<Fragment> supportFragmentInjector() {
        return supportFragmentInjector;
    }

    @Override
    public AndroidInjector<android.app.Fragment> fragmentInjector() {
        return frameworkFragmentInjector;
    }

    @Override
    protected final void onCreate(@Nullable Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
        setup(savedInstanceState);
    }

    public abstract void setup(Bundle savedInstanceState);

    private IDelegateOpt getDelegateOpt() {
        if (mDelegateOpt == null)
            mDelegateOpt = AplugManager.get().creatorActivityDelegateOpt(this);
        return mDelegateOpt;
    }

    @Override
    public <T> ObservableTransformer<T, T> bindUntilDestroy(boolean threadSwitch) {
        if (!threadSwitch) return bindUntilEvent(ActivityEvent.DESTROY);
        return new ObservableTransformer<T, T>() {
            @Override
            public ObservableSource<T> apply(@NonNull Observable<T> observable) {
                return observable.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .compose(BaseActivity.this.<T>bindUntilEvent(ActivityEvent.DESTROY));
            }
        };
    }

    @Override
    public Activity getContext() {
        return this;
    }

    @Override
    public IDialogOpt showLoading() {
        return getDelegateOpt().showLoading();
    }

    @Override
    public void hideLoading() {
        getDelegateOpt().hideLoading();
    }

    @Override
    public void onError(@StringRes int resId) {
        getDelegateOpt().onError(resId);
    }

    @Override
    public void onError(String message) {
        getDelegateOpt().onError(message);
    }

    @Override
    public void showMessage(@StringRes int resId) {
        getDelegateOpt().showMessage(resId);
    }

    @Override
    public void showMessage(String message) {
        getDelegateOpt().showMessage(message);
    }


    public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
        this.mOnBackPressedListener = onBackPressedListener;
    }

    public OnBackPressedListener getOnBackPressedListener() {
        return mOnBackPressedListener;
    }

    @Override
    public void onBackPressed() {
        if (mOnBackPressedListener == null
                || !mOnBackPressedListener.onBackPressed()) {
            super.onBackPressed();
        }
    }
}
